/* Global variables  */
var menu_strings = new Array();
var menu_mqls = new Array();
var menu_is_disease = new Array(); 
var num_elements = -1;
var biov_domain = '/base/bioventurist/';  // TODO: send this from views.py
var domain_used = 'freebase.com'; // TODO: send this from views.py
var url_read = 'http://'+domain_used+'/api/service/mqlread';


/**
 * Creates a string indicating how many topics are included on the site
 */
function createStatsLine(){

}


/**
*  Generates the drop down menu that allows the user to select
*	different examples.  Within this function, example technologies or diseases
*	are hardcoded.
* 
*/
function createDropDownList(){

	// MENU ITEM EXAMPLES 
	// Breast Cancer
	menu_strings.push('treat breast cancer');
	menu_mqls.push(getDiseaseMQL('/en/breast_cancer', biov_domain));
	menu_is_disease.push(true);
	
	// Monoclonal Antibodies
	menu_strings.push('are monoclonal antibodies');
	menu_mqls.push(getTechnologyMQL('/en/monoclonal_antibodies', biov_domain));
	menu_is_disease.push(false);

	// Nanoparticle drug delivery
	//menu_strings.push('use nanoparticle drug delivery systems');
	//menu_mqls.push(getTechnologyMQL('/en/nanoparticle_drug_delivery', biov_domain));
	//menu_is_disease.push(false);
	
	// Prostate Cancer
	menu_strings.push('treat prostate cancer');
	menu_mqls.push(getDiseaseMQL('/en/prostate_cancer', biov_domain));
	menu_is_disease.push(true);
	
	num_elements = menu_strings.length;
	
	// load the first value randomly
	var random_index=Math.floor(Math.random()*(num_elements));

	// Create the html form
/*	var h =''
	h += '<form id="aform">';
	h += '<select id="menu_select" size="1">';
	for(var i=0; i<num_elements; i++){
		if(i==random_index){
			h+= '<option id="menu_'+i+'" value="'+i+'"selected="selected">'+menu_strings[i]+'</option>';
		} else {
			h+= '<option id="menu_'+i+'" value="'+i+'">'+menu_strings[i]+'</option>';
		}
	}
	h += '</select>';
	//h += '<input id="menu_submit" type="submit" value="Show Results!">';
	h +='</form>';
	h +='<br></br>';
	$("#main_dropdown").html(h);

	// Bind loadData action to each possible selection:
 	for(var i=0;i<num_elements; i++){
		$('#menu_'+i).live("click", function (e,data) {
				// Get the mql from the element
				alert('test');
				var index = this['value'];		
				loadData(index);			
			}
		);
	}
*/ 	
	loadData(random_index);
}

/** 
* Call to load the data into the barchart.
* 
* @param {number} index 	the selection index 
*/
function loadData(index){
	var mql = menu_mqls[index];
	var menu_string = menu_strings[index];
	$('#div_menu_string').append(menu_string);
	if(menu_is_disease[index]){
		loadDataDisease(mql);
	} else {
		loadDataTechnology(mql);
	}
}

/**
 * Loads all the therapeutics that include use of th given technology.  
 * 	All technologies that are included by this technology (sub-technologies) are included
 * 	when querying for the therapeutics. 
 * 
 * @param {string} mql 	The mql query for the load.
 */
function loadDataTechnology(mql){
		perform_freebase_read(
		url_read,
		mql,
		function (msg) {
			var technology = null;
			technology = msg.result[0];
            if (!technology) return;
            
	        var name = technology.name;
            			
			// Get the list of technologies included in this technology
	        var subTechnologyList = technology.includes_technology;			
			
			// Read products for this technology and all sub-technologies (property: includes_technologies)
			var allTechnologies = '"'+name+'"';
			for(var k=0;k<subTechnologyList.length;k++){
				allTechnologies += ( k < subTechnologyList.length ? ', ' :"");
				allTechnologies += '"'+subTechnologyList[k].name+'"';
			}
			var qThera = '{"query":[{"'+biov_domain+'bv_therapeutic/biomolecule_or_target":[],"'+biov_domain+'bv_therapeutic/indication_or_disease":[{"disease":[{"name":null,"id":null}],"phase_of_development":null}],"a:type":[],"brand_name":[],"a:developed_by":[{"name":null,"id":null}],"name":null,"id":null,"sales":[{"amount":null,"area":null,"optional":true,"year":null}],"stage_of_development":null,"technology_involved|=":['+allTechnologies+'],"type":"'+biov_domain+'product"}]}'; 	
			
			// customized statement to give users when the click bar data
			var info_string = "that use " + name + " technology";
						
			// obtain and load the therapeutics for the given list of technologies 
			read_therapeutics(qThera, info_string);
												
		},
		function(m){}
	);
}

/**
 * Loads all the therapeutics that are for the given disease. 
 * 	All diseases that are included by this disease (sub-diseases) are included
 * 	when querying for the therapeutics. 
 * 
 * @param {string} mql 	The mql query for the load.
 */
function loadDataDisease(mql){
		perform_freebase_read(
		url_read,
		mql,
		function (msg) {
			var disease = null;
			disease = msg.result[0];
            if (!disease) return;
            
	        var name = disease.name;
            			
			// Technologies Included
	        var subDiseaseList = disease["/medicine/disease/includes_diseases"];
						
			// Read products for this disease and all sub-diseases
			var allDiseases = '"'+name+'"';
			for(var k=0;k<subDiseaseList.length;k++){
				allDiseases += ( k < subDiseaseList.length ? ', ' :"");
				allDiseases += '"'+subDiseaseList[k].name+'"';
			}
			var qThera = '{"query":[{"'+biov_domain+'bv_therapeutic/biomolecule_or_target":[],"'+biov_domain+'bv_therapeutic/indication_or_disease":[{"disease":[{"name|=":['+allDiseases+'],"id":null}],"phase_of_development":null}],"a:type":[],"brand_name":[],"a:developed_by":[{"name":null,"id":null}],"name":null,"id":null,"sales":[{"amount":null,"area":null,"optional":true,"year":null}],"stage_of_development":null,"type":"'+biov_domain+'product"}]}'; 	
			
			// customized statement to give users when the click bar data
			var info_string = "that is to treat " + name;
			
			read_therapeutics(qThera, info_string);
												
		},
		function(m){}
	);
}

/**
 *	Reads and loads the therapeutics for a given query.
 * 
 * @param {string} q 			The mql query for obtaining all relevent therapeutics
 * @param {string} info_string 	used when users click a given bar on the chart 
 */
function read_therapeutics(q, info_string){
	
	// Query for the therapeutics
	perform_freebase_read(
		url_read,
		q,
		function (msg2) {
	
			var therapeutics = null;
			therapeutics = msg2.result;
			if(therapeutics.length > 0){
				
				// Generate the therapeutics bar chart
				createTherapeuticsBarChartAndTable(therapeutics, info_string);		
			}
		},
		function(m){}
	);
}

/**
 * Generates an mql query to obtain all sub-technologies for the given technology
 * 
 * @param {string} id 			The freebase id of the technology
 * @param {string} biov_domain 	The bioventurist.freebase.com domain 
 */ 
function getTechnologyMQL(id, biov_domain){
 return '{"query":[{"name":null,'+
						'"guid":null,'+
						'"id":"'+id+'",'+						
						'"type":"'+biov_domain+'technology_class",'+
						'"includes_technology":[{"*":null,"optional":true}]'+
						'}]}';
}

/**
 * Generates an mql query to obtain all sub-diseases for the given disease
 * 
 * @param {string} id			The freebase id of the disease
 * @param {string} biov_domain	The bioventurist.freebase.com domain 
 */ 
function getDiseaseMQL(id, biov_domain){
 return  q  = '{"query":[{"name":null,'+
						'"type":"'+biov_domain+'bv_medical_condition",'+
						'"/medicine/disease/includes_diseases" : [{"*":null,"optional":true}],'+
						'"id" :"'+id+'",'+
						'"guid":null'+
						'}]}';				
}

/**
 * Generates a bar chart of all the therapeutics, stratified by companies (rows) and phase_of_development (cols)
 * 
 * @param {object} therapeutics	an object of all the therapeutics to be stratifiend
 * @param {string} info_string	a stock string that is desplayed to the user (amongst more customized
 * 						data) when the user clicks a bar. 
 */
function createTherapeuticsBarChartAndTable(therapeutics, info_string){
    
    // Remember all of the developers and their products
	var developers = Array();    	// the names of the developers
	var developers_stage = Array();	// the number of drugs for a given developer (row) and a given stage (column) 
	var developers_drugs = Array();	// the names of the drugs for a given developer (row) and a given stage (column)

	// Specify which phases of development to be displayed.
	var development_phases = ['Phase I Clinical Trial', 'Phase II Clinical Trial', 
							'Phase III Clinical Trial', 'On the market']
	// Colors of the bars
	var colors_vals = ['#0000FF','#0099FF','#CC6699','#CC0033'];
	
	// Initialize the data table
	var table_data = new google.visualization.DataTable();
	table_data.addColumn('string', 'Company'); //1st column is the company name
	for(var i=0;i<development_phases.length; i++){ //add columns for each phase of development
		table_data.addColumn('string', development_phases[i]);		
	}

	for (var i=0;i<therapeutics.length; i++) {
		// Get the full list of the companies that are developing the therapeutics:
		var therapeutic = therapeutics[i];
		var therapeutic_name = therapeutic.name;
		if(typeof(therapeutic.brand_name) != 'undefined'){
			if(therapeutic.brand_name.length>0){
				therapeutic_name = therapeutic.brand_name[0];
			}
		};
		var developer_list = therapeutic['a:developed_by'];
		var indications = therapeutic['/base/bioventurist/bv_therapeutic/indication_or_disease'];
		
		// Find the most developed indication
		var primary_indication_number = -1;
		for(var j=0; j<indications.length; j++){
			var phase_of_development = indications[j].phase_of_development;
			for (var k=0; k<development_phases.length; k++){
				if(phase_of_development == development_phases[k] && k>primary_indication_number){
					primary_indication_number = k;
				}
			}
		}
		
		// Record the therapeutics for each company
		for (var j=0; j<developer_list.length; j++){
			var developer = developer_list[j].name;								
			var containsDeveloper = false;
			for (var k=0; k<developers.length; k++){
				if(developer == developers[k]){
					containsDeveloper = true;	
					if(primary_indication_number > 0){
						developers_stage[k][primary_indication_number] = developers_stage[k][primary_indication_number] + 1; 
						developers_drugs[k][primary_indication_number].push(therapeutic_name); 
					}
				}
			}
			if(!containsDeveloper){
				var devIndex = developers.length; 
				developers[devIndex] = developer;
				developers_stage[devIndex] = Array();
				developers_drugs[devIndex] = Array();
				for(var a=0; a<development_phases.length; a++){
					developers_drugs[k][a] = Array();
					if(primary_indication_number > 0){	
						if(a==primary_indication_number){
							developers_stage[devIndex][a] = 1;
							developers_drugs[k][primary_indication_number].push(therapeutic_name);
						} else {
							developers_stage[devIndex][a] = 0;
						}
					}
				}				
			}
		}
								
	}	

	// Initialize the bar graph
	var barData = new google.visualization.DataTable();
	barData.addColumn('string', 'Company');
	for(var i=0;i<development_phases.length; i++){
		barData.addColumn('number', development_phases[i]);
	}
	
	var max_num_companies = 10;  // the maximum number of companies (rows) to show on the bar graph
	
	// order the companies by the total number of products:
	var developers_total = Array();
	for(var i=0;i<developers_stage.length; i++){
		var dev_stage = developers_stage[i];
		developers_total[i] = 0;
		for(var j=0;j<dev_stage.length; j++){
			developers_total[i] = developers_total[i] + dev_stage[j];
		}
	}
	var indexes = getOrder(developers_total, developers_total.length);		
	var num_use = (indexes.length>max_num_companies ? max_num_companies : indexes.length);
	barData.addRows(num_use); // specifiy the number of rows in the bar chart
	table_data.addRows(num_use); // specifiy the number of rows in the table
	var detailed_info = Array(); // An object to hold detailed information that is used when users click a bar
	
	// Load the bar and table data 
	for (var i = 0; i < num_use; i++){
		// Abbreviate the developer's name for asthetics
		detailed_info[i] = Object();
		detailed_info[i].company = developers[indexes[i]]; 
		detailed_info[i].therapeutics = Array();
		var developer_name = developers[indexes[i]].split(" ",1);
		barData.setValue(i, 0, developer_name[0]); // add the company name to the chart
		table_data.setCell(i, 0,developers[indexes[i]]); // add the company name to the table 
		for (var j=0; j<development_phases.length; j++){
			detailed_info[i].therapeutics[j] = Object();
			detailed_info[i].therapeutics[j].num = developers_stage[indexes[i]][j];
			detailed_info[i].therapeutics[j].vals = developers_drugs[indexes[i]][j];
			var value =  (developers_stage[indexes[i]][j] > 0 ? developers_stage[indexes[i]][j] : 0.1);
			barData.setValue(i, j+1, parseFloat(value));
			table_data.setCell(i,j+1,developers_drugs[indexes[i]][j].join(', '));	
		}
	}			
 
 	// Set the bar chart to the html
	$("#bar_chart_div").empty();
	var h_base = (num_use<10 ? 100 : 0);
	var chart = new google.visualization.BarChart(document.getElementById('bar_chart_div'));
	chart.draw(barData, {colors:colors_vals, is3D:true, enableTooltip:false, reverseAxis:true, width:700, height:h_base+num_use*60, legend:'bottom', isStacked:true, titleX:'Number of Theapeutics'});
		
	// catch user click events and show them the info:	
	google.visualization.events.addListener(chart, 'select', onChartClick);
	function onChartClick(e){
	 var selection = chart.getSelection();
	 var row = selection[0].row;
	 var col = selection[0].column-1;
	 outputSelection(row,col, detailed_info, development_phases, info_string);
	}
	
	// Draw the table:
	var table = new google.visualization.Table(document.getElementById('table_div'));
   	table.draw(table_data, {width: 600, allowHtml: true});
	
	
	// other companies involved but not included on the list are added as a list below the bar chart:
	$("#other_companies_div").empty();
	if(indexes.length>num_use){
		var other_companies = '<h3>Other companies involved include: </h3>';
		other_companies += '<div>'
		for(var i=num_use;i<indexes.length; i++){
			other_companies += developers[indexes[i]];
			other_companies += (i<indexes.length-1 ? ', ' : '');
		}
		other_companies += '</div>'
		other_companies = $(other_companies);
		$("#other_companies_div").append(other_companies);
	}
}

/**
 * Outputs data to the user based on their clicked selection.  Currently an alert is used to inform the user.
 * 
 * @param {number} row 				the selected row
 * @param {number} col				the selected column
 * @param {string} detailed_info		information to be used to generate text for the user
 * @param {array}  indication_types	the set of development_phases considered
 * @param {string} info_string		a stock string tagged to the envent
 */
function outputSelection(row,col, detailed_info, development_phases, info_string){
	var comp_name = detailed_info[row].company;
	var num_vals = detailed_info[row].therapeutics[col].num;
	var vals = detailed_info[row].therapeutics[col].vals;

	var names_string = '';
	for(var k=0;k<vals.length; k++){
		var therapeutic_name = vals[k];
		names_string += therapeutic_name;
		names_string += (k<vals.length-1 ? ', ' :'');
	} 
	var alert_string = comp_name+ ' has ' +num_vals+ (num_vals>1 ? ' therapeutics' : ' therapeutic');
	alert_string += (col<3 ? ' in ' :'') +development_phases[col]+', '+ names_string +', '
	alert_string += info_string;
	alert(alert_string);
}

/**
 * Randomizes the given array
 * 
 * @param {array} myArray	array to be randomized
 */
function fisherYates ( myArray ) {
  var i = myArray.length;
  if ( i == 0 ) return false;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = myArray[i];
     var tempj = myArray[j];
     myArray[i] = tempj;
     myArray[j] = tempi;
   }
}
 